#ifndef __CLX_DATA_HPP__
#define __CLX_DATA_HPP__

#include <unordered_map>
#include <sstream>
#include "util.hpp"

namespace clx_cloud {
    class DataManager {
		private:
			std::string _backup_file;  // 持久化存储文件
			std::unordered_map<std::string, std::string> _table; // 内存中以hash表存储
		public:
            DataManager(const std::string &backup_file) :_backup_file(backup_file) {
                InitLoad();
            }
            ~DataManager() {
            }
            bool Storage() {
                // 1、获取所有的备份信息
                std::stringstream ss;
                for ( auto it = _table.begin(); it != _table.end(); it++) {
                    // 2、将所有信息进行指定持久化格式的组织
                    ss << it->first << " " << it->second << "\n";
                }
                // 3、持久化存储
                FileUtil fu(_backup_file);
                const std::string s = ss.str();
                fu.SetContent(&s);
                return true;
            }              

            size_t Split(const std::string& str, const std::string& sep, std::vector<std::string>* array) {
                size_t pos = 0, index = 0;
                pos = str.find(sep, index);
                while (pos != std::string::npos) {
                    if (pos != index)
                        array->push_back(str.substr(index, pos - index));
                    index = pos + sep.size();
                    pos = str.find(sep, index);
                }
                if (index < str.size()) {
                    array->push_back(str.substr(index));
                }
                return array->size();
            }

            // 初始化加载，在每次系统重启都要加载以前的数据
            bool InitLoad() {          
                // 1、从文件中读取所有数据
                FileUtil fu(_backup_file);
                std::string body;
                // 2、进行数据解析，添加到表中
                fu.GetContent(&body);
                std::vector<std::string> array;
                Split(body, "\n", &array);
                for (auto& a : array) {
                    std::vector<std::string> tmp;
                    Split(a, " ", &tmp);
                    if (tmp.size() == 2) 
                        _table[tmp[0]] = tmp[1];
                }
                return true;
            } 

            // 每次数据新增或者修改都需要重新持久化存储，避免数据丢失
            bool Insert(const std::string &key, const std::string &val) {   
                _table[key] = val;
                Storage();
                return true;
            }
            bool Update(const std::string &key, const std::string &val) {   // 修改
                _table[key] = val;
                Storage();
                return true;
            }   
            bool GetOneByKey(const std::string &key, std::string *val) {
                auto it = _table.find(key);
                if (it == _table.end()) 
                    return false;
                *val = it->second;
                return true;
            }
    };
}

#endif
